/**
 * Copyright (c) 2020 kedacom
 * OpenATC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 * http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 **/
package com.openatc.comm.model;

import com.openatc.comm.data.MessageData;
import com.openatc.comm.ocp.OcpDataEscape;
import com.openatc.comm.ocp.OcpDataPackUpPack;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import static com.openatc.comm.common.CommunicationType.EXANGE_TYPE_DEVICE;
import static com.openatc.comm.common.CosntDataDefine.setrequest;

public class ocpMessage implements Message {
    private static final int RECVBUFFER = 64 * 1024;
    @Override
    public PackData pack(MessageData sendMsg) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        PackData packData = null;
        // 将OpenATC消息转换为OCP协议
        OcpDataPackUpPack ocpDataPackUpPack = new OcpDataPackUpPack();
        byte[] dataSchedule = ocpDataPackUpPack.PackDataSchedule(sendMsg);
        if (ocpDataPackUpPack.isZero(dataSchedule)) {
            packData = null;
        } else {
            // 进行OCP协议字符转义
            byte[] packDataBuff = new byte[RECVBUFFER];
            int packBuffLen = 0;
            // 密钥认证设备的set请求需要开启密钥校验
            if(sendMsg.getAuth() == 3 || sendMsg.getAuth() == 2 && sendMsg.getOperation().equals(setrequest)){
                String secretkey = sendMsg.getSecretkey();
                byte[] checkdata = addBytes(dataSchedule, secretkey.getBytes());
                byte[] md5Bytes = MessageDigest.getInstance("md5").digest( checkdata );

                packBuffLen = OcpDataEscape.packBuff(dataSchedule, packDataBuff, md5Bytes);

//                System.out.println("checkdata: " + BytePrintAsString(checkdata));
//                System.out.println("md5Bytes: " + BytePrintAsString(md5Bytes));
//                System.out.println("senddata: " + BytePrintAsString(packDataBuff,packBuffLen));

            }
            else{
                packBuffLen = OcpDataEscape.packBuff(dataSchedule, packDataBuff);

            }
            packData = new PackData(packDataBuff, packBuffLen);
        }
        return packData;
    }




    @Override
    public MessageData uppack(byte[] dataSource,int length) throws UnsupportedEncodingException {
        if (dataSource == null) {
            return null;
        }
        MessageData responseData = new MessageData();
        byte[] dataSchedule = new byte[length];
        int upPackBuffLen = OcpDataEscape.upPackBuff(dataSource, dataSchedule);
        if (upPackBuffLen != 0) {
            OcpDataPackUpPack.ReadDataSchedule(responseData, dataSchedule, upPackBuffLen);
        }
        return responseData;
    }

    @Override
    public int geyExangeType() {
        return EXANGE_TYPE_DEVICE;
    }

    public byte[] addBytes(byte[] data1, byte[] data2) {
        byte[] data3 = new byte[data1.length + data2.length];
        System.arraycopy(data1, 0, data3, 0, data1.length);
        System.arraycopy(data2, 0, data3, data1.length, data2.length);
        return data3;
    }
}
